package info.fqtech.skb.client.utils;

import org.apache.commons.codec.digest.DigestUtils;
import org.apache.commons.lang3.StringUtils;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import java.util.regex.Pattern;

/**
 * @author YASSER   作者 E-mail:   450153554@qq.com
 * @date: 2018-09-03 15:30
 * @version: 1.0.0
 * @description: 签名验证工具类
 * @modified: <文件修改说明>
 */
public class SignUtils {
    /**
     * 默认编码规则
     */
    private static final String CHARSET = "UTF-8";

    /**
     * 获取字符串的md5数据
     * @param str -- 原始数据
     * @return
     */
    public static String getMD5(String str) {
        String md5Str = DigestUtils.md5Hex(str);
        return md5Str;
    }

    /**
     * 获取md5的签名数据
     * 1、对请求参数(刨去sign、status、msg和value为空)根据参数名称的ASCII字典序排序
     * 2、将请求参数生成字符串 strA = "key1=value1&key2=value2&key3=value3";
     * 3、将请求参数生成的字符串拼接上秘钥(md5key)，md5Str = strA + "&key=md5Key";
     * 4、对拼接的md5Str字符串进行md5，获得签名
     * @param requestMap -- 请求参数集合
     * @param md5Key -- 商户秘钥
     * @return
     */
    public static String getSignOfMD5(Map<String, String> requestMap, String md5Key) {
        String[] keys = new String[requestMap.size()];
        requestMap.keySet().toArray(keys);
        Arrays.sort(keys);
        StringBuilder stringBuilder = new StringBuilder();
        for (String key : keys) {
            if(Objects.equals("sign", key) || Objects.equals("status", key) || Objects.equals("msg", key)) {
                continue;
            }
            String value = requestMap.get(key);
            if(StringUtils.isBlank(value)) {
                continue;
            }
            stringBuilder.append(key);
            stringBuilder.append("=" + value);
            stringBuilder.append("&");
        }
        stringBuilder.append("key=" + md5Key);
        return getMD5(stringBuilder.toString());
    }

    /**
     * 检查签名是否正确
     * @param requestMap -- 请求数据
     * @param sign -- 签名
     * @param md5Key -- 签名
     * @return
     */
    public static boolean isRightSign(Map<String, String> requestMap, String sign, String md5Key) {
        String signStr = getSignOfMD5(requestMap, md5Key);
        return Objects.equals(sign, signStr);
    }

    /**
     * 检查通知地址是否合法。防止sql注入
     * 通知地址中不得包含 select|update|delete
     * @param notifyUrl
     * @return
     */
    public static boolean isNotRightNotifyUrl(String notifyUrl) {
        String rex = "(select|update|union|and|or|delete|insert|trancate|char|into|substr|ascii|declare|exec|count|master|into|drop|execute)";
        Pattern sqlPattern = Pattern.compile(rex, Pattern.CASE_INSENSITIVE);
        return sqlPattern.matcher(notifyUrl).find();
    }

    public static void main(String[] args) {
        // 支付状态成功，进行数据签名验证
        Map<String, String> responseMap = new HashMap<>(8);
        responseMap.put("merCode", "891347");
        responseMap.put("account", "8913472801");
        responseMap.put("orderNo", "1539910251755");
        responseMap.put("orderAmount", "500.00");
        responseMap.put("realPayAmount", "499.96");

        String responseSign = "230d6d4c59d2f5a06acb0bd9d47b2808";
        System.out.println(getSignOfMD5(responseMap, "b128aa1e61244a9fb9147beba248a4cd"));

    }

}
